home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-02-19 | 14.2 KB | 500 lines | [TEXT/CWIE] |
-
- #include "Application.h"
- #include "AbstractDocument.h"
- #include "ScriptableDBDocument.h"
- #include "ResolveObjectSpecifier.h"
- #include "FileIterators.h"
- #include "MoreStrings.h"
-
- #include <AppleEvents.h>
- #include <AERegistry.h>
- #include <ASRegistry.h>
- #include <TextUtils.h>
-
- #include "Exceptions.h"
-
- TPropertyDescription TApplication::fPropertiesOfClass[] = {
- // "color" is temporary for resolution mode
- { pColor, 0, typeLongInteger, typeLongInteger },
- { pSelection, 0, typeAEList, typeObjectSpecifier },
- { pIsFrontProcess, 0, typeBoolean, typeBoolean },
- { pClipboard, 0, typeObjectSpecifier, typeObjectSpecifier },
- { pInsertionLoc, 0, typeObjectSpecifier, typeObjectSpecifier }
- };
-
- #pragma segment ObjectResident
- ImplementClassData(TApplication, clApplication);
-
- TApplication* TApplication::gApplication = nil;
-
- //--------------------------------------------------------------------------------
- // TApplication::TApplication
- //--------------------------------------------------------------------------------
- TApplication::TApplication() :
- fCloseRequestsPending(false),
- fResolutionMode(3)
- {
- //
- // Remember our PSN and application FileSpec
- //
- GetCurrentProcess(&fPSN);
- fFileSpec = TFSSpecification(fPSN);
- } // TApplication::TApplication
-
- //--------------------------------------------------------------------------------
- // TApplication::ObjectClass
- //--------------------------------------------------------------------------------
- DescType TApplication::ObjectClass(const TAETransaction&, Boolean /*recordedClass*/)
- {
- return cApplication;
- }
-
- //--------------------------------------------------------------------------------
- // TApplication::DerivedFromOSLClass
- //--------------------------------------------------------------------------------
- Boolean TApplication::DerivedFromOSLClass(const TAETransaction& t, DescType objectClass)
- {
- return ((objectClass == cApplication) || Inherited::DerivedFromOSLClass(t, objectClass));
- }
-
- class TNullContainerIterator : public TAbstractObjectIterator
- {
- public:
- TNullContainerIterator() {};
- virtual ~TNullContainerIterator();
-
- virtual void Reset(const TAETransaction&, Boolean iterationDirection = kForwardIteration);
- virtual Boolean More(const TAETransaction&) const;
- virtual void Next(const TAETransaction&);
-
- virtual TAbstractScriptableObject* Current(const TAETransaction&);
- virtual void RemoveCurrent(const TAETransaction& t);
-
- virtual TAbstractScriptableObject* GetNamedElement(const TAETransaction& t, DescType desiredClass, TDescriptor nameDesc);
-
- private:
- TDocumentLoop fDocumentIter;
- };
-
- TNullContainerIterator::~TNullContainerIterator()
- {
- }
-
- void TNullContainerIterator::Reset(const TAETransaction& t, Boolean iterationDirection /*= kForwardIteration*/)
- {
- fDocumentIter.Reset(t, iterationDirection);
- }
-
- Boolean TNullContainerIterator::More(const TAETransaction& t) const
- {
- return fDocumentIter.More(t);
- }
-
- void TNullContainerIterator::Next(const TAETransaction& t)
- {
- fDocumentIter.Next(t);
- }
-
- TAbstractScriptableObject* TNullContainerIterator::Current(const TAETransaction& t)
- {
- return fDocumentIter.Current(t);
- }
-
- void TNullContainerIterator::RemoveCurrent(const TAETransaction& t)
- {
- fDocumentIter.RemoveCurrent(t);
- }
-
- TAbstractScriptableObject* TNullContainerIterator::GetNamedElement(const TAETransaction& t, DescType desiredClass, TDescriptor nameDesc)
- {
- TAbstractScriptableObject* result = nil;
-
- //
- // First, check to see if the nameDesc is an int64; if so,
- // don't quibble over "document id int64" vs "document int64",
- // just return the appropriate document.
- //
- if(nameDesc.DescriptorType() == 'in64')
- {
- result = TApplication::Instance()->AccessByUniqueID(t, desiredClass, nameDesc);
- }
- else
- {
- result = fDocumentIter.GetNamedElement(t, desiredClass, nameDesc);
- }
-
- //
- // If we couldn't find an open document with the given name, then
- // search the disk (that contains the running application) for
- // a document with the given name
- //
- if(result == nil)
- {
- TStackBasedString fileName = nameDesc;
-
- for(TCatalogSearchIterator iter(TApplication::Instance()->AppFileVRefNum(), fileName, 'db ', 'db++', kSeachFilesOnly | kNameMustMatchExactly | kOnlyOneMatch); iter.More(); iter.Next())
- {
- result = TScriptableDBDocument::OpenDatabase(iter.Current());
- }
- }
-
- return result;
- }
-
- //--------------------------------------------------------------------------------
- // TApplication::ElementIterator
- //--------------------------------------------------------------------------------
- TAbstractObjectIterator* TApplication::ElementIterator(const TAETransaction&)
- {
- // return new TDocumentLoop();
- return new TNullContainerIterator();
- }
-
- //--------------------------------------------------------------------------------
- // TApplication::Idle
- //
- // Called once per waitnextevent
- //--------------------------------------------------------------------------------
- void TApplication::Idle()
- {
- if(fCloseRequestsPending)
- this->ProcessCloseRequest();
- }
-
- //--------------------------------------------------------------------------------
- // TApplication::TearDownApplication
- //--------------------------------------------------------------------------------
- void TApplication::TearDownApplication()
- {
- //
- // Close all open documents (documents should save themselves before closing)
- //
- for(TDocumentLoop iter; iter.More(TAETransaction()); iter.Next(TAETransaction()))
- {
- TAbstractDocument* doc = iter.RemoveCurrentDocument(TAETransaction());
- delete doc;
- }
- } // TApplication::TearDownApplication
-
- //--------------------------------------------------------------------------------
- // TApplication::MarkForClose
- //--------------------------------------------------------------------------------
- void TApplication::MarkForClose(TAbstractDocument* doc)
- {
- fCloseRequestsPending = true;
- doc->MarkForClose();
- } // TApplication::MarkForClose
-
- //--------------------------------------------------------------------------------
- // TApplication::ProcessCloseRequest
- //--------------------------------------------------------------------------------
- void TApplication::ProcessCloseRequest()
- {
- Boolean requestsPending = false;
-
- if(fCloseRequestsPending)
- {
- for(TDocumentLoop iter; iter.More(TAETransaction()); iter.Next(TAETransaction()))
- {
- if(iter.CurrentDocument()->CloseRequested())
- {
- //
- // Also test to see if doc can be closed
- // (wouldn't want to close a document that
- // some thread was working with)
- //
- if(true)
- {
- TAbstractDocument* doc = iter.RemoveCurrentDocument(TAETransaction());
- delete doc;
- }
- else
- requestsPending = true;
- }
- }
- fCloseRequestsPending = requestsPending;
- }
- } // TApplication::ProcessCloseRequest
-
- //--------------------------------------------------------------------------------
- // TApplication::FindDocument
- //--------------------------------------------------------------------------------
- TAbstractDocument* TApplication::FindDocument(Int64 documentID, Boolean searchForAndOpen /* = false */)
- {
- TAbstractDocument* doc = nil;
-
- for(TDocumentLoop iter; iter.More(TAETransaction()); iter.Next(TAETransaction()))
- {
- if(iter.CurrentDocument()->DocumentIdentifier() == documentID)
- {
- doc = iter.CurrentDocument();
- break;
- }
- }
-
- if((doc == nil) && (searchForAndOpen == true))
- {
- //
- // Look for a document somewhere in our search path
- // that has the given unique ID
- //
- // In the future, it would be a very good idea to cache
- // the FSSpec and document ID of databases that we have
- // seen, and look for entries in the cache before searching
- // the entire disk. For now we always search the disk,
- // though.
- //
- for(TCatalogSearchIterator iter(TApplication::Instance()->AppFileVRefNum(), nil, 'db ', 'db++', kSeachFilesOnly); iter.More(); iter.Next())
- {
- doc = TScriptableDBDocument::OpenDatabase(iter.Current(), documentID);
- if(doc != nil)
- break;
- }
- }
-
- return doc;
- }
-
- //--------------------------------------------------------------------------------
- // TApplication::FindDocument
- //--------------------------------------------------------------------------------
- TAbstractDocument* TApplication::FindDocument(TFSSpecification& fileSpec, Boolean openDocument /*= false*/)
- {
- TAbstractDocument* doc = nil;
-
- for(TDocumentLoop iter; iter.More(TAETransaction()); iter.Next(TAETransaction()))
- {
- TFSSpecification currentFSSpec;
-
- if(iter.CurrentDocument()->DocumentFSSpecification(currentFSSpec) == true)
- {
- if(fileSpec == currentFSSpec)
- {
- doc = iter.CurrentDocument();
- break;
- }
- }
- }
-
- if((doc == nil) && (openDocument == true))
- doc = TScriptableDBDocument::OpenDatabase(fileSpec);
-
- return doc;
- }
-
- //--------------------------------------------------------------------------------
- // TApplication::DocumentIndex
- //--------------------------------------------------------------------------------
- long TApplication::DocumentIndex(Int64 documentID)
- {
- long docIndex = 0;
- Boolean found = false;
-
- for(TDocumentLoop iter; iter.More(TAETransaction()); iter.Next(TAETransaction()))
- {
- ++docIndex;
-
- if(iter.CurrentDocument()->DocumentIdentifier() == documentID)
- {
- found = true;
- break;
- }
- }
-
- if(found == false)
- FailErr(errAENoSuchObject);
-
- return docIndex;
- }
-
- //--------------------------------------------------------------------------------
- // TApplication::AccessByUniqueID
- //--------------------------------------------------------------------------------
- TAbstractScriptableObject* TApplication::AccessByUniqueID(const TAETransaction& t, DescType desiredClass, TDescriptor uniqueID)
- {
- TAbstractScriptableObject* result = nil;
-
- if(desiredClass == cDocument)
- {
- result = this->FindDocument(uniqueID.GetSInt64Data(), true);
- }
- else
- result = Inherited::AccessByUniqueID(t, desiredClass, uniqueID);
-
- return result;
- } // TApplication::AccessByUniqueID
-
- //--------------------------------------------------------------------------------
- // TApplication::GetProperty
- //--------------------------------------------------------------------------------
- TDescriptor TApplication::GetProperty(const TAETransaction& t, DescType propertyName, DescType desiredType, unsigned long additionalInfo)
- {
- TDescriptor result;
-
- switch(propertyName)
- {
- case pName:
- {
- #if 0
- //
- // •••Need to ask the process manager what our name is
- //
- result.MakeString("\pdb+");
- #endif
- break;
- }
-
- //
- // This is the resolution mode: use "color" temporarily
- //
- case pColor:
- {
- result.SetSInt32Data(fResolutionMode);
- break;
- }
-
- default:
- {
- result = Inherited::GetProperty(t, propertyName, desiredType, additionalInfo);
- }
- }
-
- return result;
- }
-
- //--------------------------------------------------------------------------------
- // TApplication::SetProperty
- //--------------------------------------------------------------------------------
- void TApplication::SetProperty(const TAETransaction& t, DescType propertyName, TDescriptor& data, unsigned long additionalInfo)
- {
- switch(propertyName)
- {
- //
- // This is the resolution mode: use "color" temporarily
- //
- case pColor:
- {
- this->SetResolutionMode(data.GetSInt32Data());
- break;
- }
-
- default:
- {
- Inherited::SetProperty(t, propertyName, data, additionalInfo);
- }
- }
- }
-
- //--------------------------------------------------------------------------------
- // TApplication::AECommand
- //--------------------------------------------------------------------------------
- TDescriptor TApplication::AECommand(const TAETransaction& t, long aeCommandID, TAbstractScriptableObject* auxObjects, long auxInfo)
- {
- TDescriptor result;
- TDescriptor intermediate;
-
- switch(aeCommandID)
- {
- case kAEOpen:
- {
- TDescriptor openSpecDesc = t.Message().GetDescriptorParameter(keyDirectObject);
- for(TDescriptorIterator iter(openSpecDesc); iter.More(); iter.Next())
- {
- TFSSpecification openFSSpec(iter.Current());
-
- TAbstractDocument* document = this->FindDocument(openFSSpec, true);
- if(document != nil)
- {
- intermediate = document->BuildObjectSpecifier(t);
- result.AppendListAndDispose(intermediate);
- }
- }
- openSpecDesc.Dispose();
- break;
- }
-
- default:
- {
- result = Inherited::AECommand(t, aeCommandID, auxObjects, auxInfo);
- break;
- }
- }
-
- return result;
- }
-
- //--------------------------------------------------------------------------------
- // TApplication::CreateNewElement
- //--------------------------------------------------------------------------------
- TAbstractScriptableObject* TApplication::CreateNewElement(const TAETransaction& t, DescType newObjectClass, TDescriptor initialData, TDescriptor initialProperties, Boolean& usedInitialData, Boolean& usedInitialProperties)
- {
- TAbstractScriptableObject* result = nil;
-
- //
- // The application can only create documents
- //
- if(newObjectClass == cDocument)
- {
- //
- // If we create a new document, it will automatically
- // be added to the global documents list
- //
- result = TScriptableDBDocument::NewDatabase();
- }
- else
- result = Inherited::CreateNewElement(t, newObjectClass, initialData, initialProperties, usedInitialData, usedInitialProperties);
-
- return result;
- }
-
- //--------------------------------------------------------------------------------
- // TApplication::SetResolutionMode
- //--------------------------------------------------------------------------------
- void TApplication::SetResolutionMode(long newValue)
- {
- switch(newValue)
- {
- //
- // Don't do anything special, not even marking
- // (NOTE: In this mode, object specifier resolutions
- // that have more than one result will not work, as
- // we do not have code that deals with AE-lists-of-tokens)
- //
- case 0:
- TDescriptor::SetCallbackFlags(kAEIDoMinimum);
- InstallPreResolveProc(nil);
- break;
-
- //
- // Let the OSL resolve all specifiers, including whose clauses
- //
- case 1:
- TDescriptor::SetCallbackFlags(kAEIDoMarking);
- InstallPreResolveProc(nil);
- break;
-
- //
- // OSL does most resolution, but we do whose clauses
- //
- case 2:
- TDescriptor::SetCallbackFlags(kAEIDoMarking + kAEIDoWhose);
- InstallPreResolveProc(nil);
- break;
-
- //
- // We do all object specifier resolution without ever calling OSL
- // (but set the callback flags anyway, just in case).
- //
- case 3:
- TDescriptor::SetCallbackFlags(kAEIDoMarking + kAEIDoWhose);
- InstallPreResolveProc(ResolveObjectSpecifier);
- break;
-
- default:
- newValue = fResolutionMode;
- break;
- }
- fResolutionMode = newValue;
- }
-
-